package lxs.swift.collector.wrap;


import org.jetbrains.annotations.NotNull;

import java.util.Objects;
import java.util.function.Supplier;

public interface Wrapper<T, E extends Throwable, W extends Wrapper<T, E, W>> {

    T unwrap() throws E;

    T unwrapOr(@NotNull Supplier<T> supplier);

    W and(@NotNull W wrapper);

    W or(@NotNull W wrapper);

    W replace(boolean bool, @NotNull Supplier<T> supplier);

    W copy();

    default T unwrapOr(T v) {
        return unwrapOr(() -> v);
    }

    default T expect(@NotNull String error) {
        Objects.requireNonNull(error);
        try {
            return this.unwrap();
        } catch (Throwable e) {
            throw new RuntimeException(error);
        }
    }

    default <EE extends Throwable> T expect(@NotNull EE ee) throws EE {
        Objects.requireNonNull(ee);
        try {
            return this.unwrap();
        } catch (Throwable e) {
            throw ee;
        }
    }

    default W replace(boolean bool, T value) {
        return replace(bool, () -> value);
    }

    default W replace(T value) {
        return replace(true, () -> value);
    }
}
